package com.shigen.demo.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shigen.demo.config.ConfigProperty;
import com.shigen.demo.entity.User;
import com.shigen.demo.entity.UserInfo;
import com.shigen.demo.entity.req.UserInfoReq;
import com.shigen.demo.entity.req.UserInfoReq.OpBase;
import com.shigen.demo.mapper.UserInfoMapper;
import com.shigen.demo.mapper.UserMapper;
import com.shigen.demo.service.IBaseUserFileService;
import com.shigen.demo.service.IUserInfoService;
import com.shigen.demo.service.UserService;
import java.io.File;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

@Service
@Slf4j
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {

  @Resource
  private UserMapper userMapper;
  @Resource
  private ConfigProperty configProperty;
  @Resource
  private UserService userService;
  @Resource
  private IBaseUserFileService baseUserFileService;


  @Transactional(rollbackFor = Exception.class)
  public Integer addUserInfo(OpBase opBase) {
    // 一定是先在user表中插入信息，然后再在userinfo中插入
    Integer maxUserid = userMapper.getMaxUserid();

    Integer userId = maxUserid + 1;

    String newPassword = DigestUtils.md5DigestAsHex((configProperty.getPasswordSalt() + userId).getBytes());
    User user = new User().setId(userId).setPassword(newPassword);

    userMapper.insert(user);

    // 获得当前用户信息
    UserInfo userInfo1 = userService.getUserInfo();

    // 插入到userinfo表
    UserInfo userInfo = new UserInfo()
        .setUserId(userId)
        .setUserName(opBase.getUserName())
        .setSex(opBase.getSex())
        .setEmail(opBase.getEmail())
        .setPhone(opBase.getPhone())
        .setRegion(opBase.getRegion())
        .setRegTime(DateTime.now())
        .setAddress(opBase.getAddress())
        .setCreateUserId(userInfo1.getUserId())
        .setCreateUserName(userInfo1.getUserName())
        .setIsActive(true)
        .setIsDel(false);
    try {
      userInfo.setBirthday(DateUtil.parse(opBase.getBirthday()));
    } catch (Exception e) {
      log.error("{}: birthday 解析失败: exception: {}", DateUtil.now(), e.getMessage());
    }
    int insert = getBaseMapper().insert(userInfo);
    return insert == 1 ? userId : -1;
  }

  @Transactional(rollbackFor = Exception.class)
  public Integer delBatch(List<Long> userIds) {
    if (CollectionUtil.isNotEmpty(userIds)) {
      userMapper.deleteBatchIds(userIds);
      return getBaseMapper().deleteBatchUserIds(userIds);
    }
    return 0;
  }

  public Integer updateUserInfoStatus(Integer userId, boolean status) {
    boolean update = lambdaUpdate().set(UserInfo::getIsActive, status).eq(UserInfo::getUserId, userId).update();
    return update ? 1 : 0;
  }

  public Integer updateUserInfo(OpBase opBase) {
    Date birth = null;
    String birthday = opBase.getBirthday();
    try {
      birth = DateUtil.parse(birthday);
    } catch (Exception e) {
      log.error("{}: birthday 解析失败: exception: {}", DateUtil.now(), e.getMessage());
    }

    boolean update = lambdaUpdate()
        .set(UserInfo::getUserName, opBase.getUserName())
        .set(UserInfo::getSex, opBase.getSex())
        .set(UserInfo::getEmail, opBase.getEmail())
        .set(UserInfo::getPhone, opBase.getPhone())
        .set(birth != null, UserInfo::getBirthday, birth)
        .set(UserInfo::getRegion, opBase.getRegion())
        .set(UserInfo::getAddress, opBase.getAddress())
        .eq(UserInfo::getUserId, opBase.getUserId())
        .update();
    return update ? 1 : 0;
  }

  public IPage<UserInfo> getAllUserInfo(UserInfoReq.QueryItem query) {
    Page<UserInfo> page = new Page<>(query.getPagenum(), query.getPagesize());
    String param = query.getParam();
    LambdaQueryChainWrapper<UserInfo> chainWrapper = lambdaQuery();
    if (StrUtil.isNotEmpty(param)) {
      chainWrapper.likeRight(UserInfo::getUserId, param).or().likeRight(UserInfo::getUserName, param);
    }
    return chainWrapper.orderByDesc(UserInfo::getRegTime).page(page);
  }

  /**
   * 查询单个用户的信息
   *
   * @param userId
   * @return
   */
  public UserInfo getUserInfoByUserId(Integer userId) {
    return lambdaQuery().eq(userId != null, UserInfo::getUserId, userId).eq(UserInfo::getIsDel, false).one();
  }

  @Transactional(rollbackFor = Exception.class)
  public String updateUserIcon(MultipartFile file) {
    UserInfo userInfo = userService.getUserInfo();
    Integer userId = userInfo.getUserId();

    String originalIcon = getBaseMapper().getUserIcon(userId);

    String fileName = baseUserFileService.uploadFile(file, configProperty.getIconSavePath());

    boolean update = lambdaUpdate().set(UserInfo::getIconPath, fileName).eq(UserInfo::getUserId, userId).update();
    if (update) {
      // 从服务器删除原来的icon
      if (StrUtil.isNotEmpty(originalIcon)) {
        File originalIconFile = new File(configProperty.getIconSavePath(), originalIcon);
        FileUtil.del(originalIconFile);
      }
      return fileName;
    } else {
      // 防止误删父文件夹
      if (StrUtil.isNotEmpty(fileName)){
        FileUtil.del(new File(configProperty.getIconSavePath(), fileName));
      }
      return originalIcon;
    }
  }

  public String getUserIcon(Integer userid) {
    return getBaseMapper().getUserIcon(userid);
  }
}
